package com.liaoyifan.core.model;

import com.liaoyifan.core.converter.PageConverter;
import com.liaoyifan.core.enums.PoolNameEnum;
import com.liaoyifan.core.query.PageQuery;
import com.liaoyifan.core.thread.ThreadPool;
import com.liaoyifan.core.util.Try;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
import java.util.concurrent.Future;
import java.util.function.Supplier;
import lombok.Data;

@SuppressWarnings("unused")
@Data
public class Page<T> implements Serializable {

    @Serial private static final long serialVersionUID = 1L;

    @Schema(description = "页数据")
    private List<T> list;

    @Schema(description = "总条数")
    private Long total;

    @Schema(description = "页大小")
    private Long limit;

    @Schema(description = "当前页")
    private Long current;

    @Schema(description = "总页数")
    public Long getPages() {
        if (this.limit == null || this.total == null) {
            return null;
        }
        long pages = this.total / this.limit;
        if (this.total % this.limit != 0L) {
            ++pages;
        }
        return pages;
    }

    public static <T> Page<T> of(PageQuery query, Supplier<List<T>> list, Supplier<Long> count) {
        Page<T> page = new Page<>();
        if (query != null && query.getStart() != null) {
            Future<Long> future =
                    ThreadPool.submit(PoolNameEnum.PAGE.getValue(), e -> e.submit(count::get));
            page.setList(list.get());
            page.setCurrent(query.getCurrent());
            page.setLimit(query.getLimit());
            page.setTotal(Try.run(() -> future.get()));
            return page;
        } else {
            page.setList(list.get());
            page.setCurrent(1L);
            page.setLimit((long) page.getList().size());
            page.setTotal(page.getLimit());
        }
        return page;
    }

    public static <T> Page<T> of(com.mybatisflex.core.paginate.Page<T> page) {
        return PageConverter.of(page);
    }
}
